package com.vpen.block.task;

import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import java.util.concurrent.*;

/**
 * @version: 1.0
 * @author: Vpen
 * @date: 2021/11/20 22:36
 * @content:
 */
@Component
public class PoolConfig {
    /**
     * 工作线程
     */
    private static final Integer corePoolSize = 5;
    /**
     * 最大工作线程
     */
    private static final Integer maximumPoolSize = 10;
    /**
     * 线程空闲回收时间
     */
    private static final Long keepAliveTime = 200L;
    /**
     * 任务等待队列
     */
    private static final BlockingQueue<Runnable> workQueue = new LinkedBlockingQueue<>();
    /**
     * 拒绝策列
     */
    private static final RejectedExecutionHandler handler = new ThreadPoolExecutor.DiscardPolicy();
    /**
     * 核心线程
     */
    private static ThreadPoolExecutor executor;


    /**
     * RejectedExecutionHandler 拒绝策列
     * ThreadPoolExecutor.AbortPolicy(默认)       丢弃任务并抛出RejectedExecutionException异常
     *
     * ThreadPoolExecutor.DiscardPolicy          丢弃新任务，不抛出异常
     *
     * ThreadPoolExecutor.DiscardOldestPolicy    丢弃队列老任务，不抛出异常
     *
     * ThreadPoolExecutor.CallerRunsPolicy       由调用线程处理该任务，不抛出异常
     *
     * 阻塞队列
     * new ArrayBlockingQueue<>()          基于数组的先进先出队列，有界
     *
     * new LinkedBlockingQueue<>()         基于链表的先进先出队列，无界
     *
     * new SynchronousQueue<>()            无缓冲的等待队列，无界
     **/
    @PostConstruct
    public void initPool() {
        executor = new ThreadPoolExecutor(corePoolSize,
                maximumPoolSize,
                keepAliveTime,
                TimeUnit.SECONDS,
                workQueue,
                Executors.defaultThreadFactory(),
                handler);
    }

    /**
     * 获取线程池
     *
     * @return java.util.concurrent.ThreadPoolExecutor
     * @author Vpen
     * @date 2021/11/21 11:48
     * @name getExecutor
     **/
    public ThreadPoolExecutor getExecutor() {
        return executor;
    }

    /**
     * 执行给定的任务。
     * 任务可以在新线程或现有池线程中执行。
     * 如果由于此执行器已关闭或已达到其容量而无法提交任务执行，
     * 则该任务将由当前RejectedExecutionHandler处理。
     *
     * @param task task
     * @return void
     * @author Vpen
     * @date 2021/11/21 11:40
     * @name startTask
     **/
    public void startTask(Runnable task) {
        executor.execute(task);
    }


    /**
     * 有序关机，执行以前提交的任务，但不接受新任务。
     * 如果调用已经关闭，则调用没有其他效果。
     * 此方法不会等待以前提交的任务完成执行。
     * 使用此选项可以完成此操作。
     *
     * @return void
     * @author Vpen
     * @date 2021/11/21 11:41
     * @name stopDown
     **/
    public void shutdown() {
        executor.shutdown();
    }
}
